#!/usr/bin/python
# coding=utf-8
__author__ = 'good'
__createday__ = '2014-12-11'

import os
import subprocess
import zipfile
import time
from datetime import datetime
from flask.ext.script import Manager
from ..extensions import db as database
from config import BACKUP_DIR, LOG_DIR, UPLOAD_FOLDER, BASEDIR
from ..tasks import backup_mail

if os.name == 'nt':
    import sys

    reload(sys)
    sys.setdefaultencoding("utf-8")

BackupManager = Manager(help=u'备份一些东西')
msg = ''


def Uploads():
    u"""获取上传的附件列表"""
    global msg
    msg = msg + str(datetime.now()) + ' -> ' + u'加载上传文件...' + '<br/>'
    file_list = []
    for root, dirs, files in os.walk(UPLOAD_FOLDER):
        for name in files:
            file_list.append(os.path.join(root, name))
    msg = msg + str(datetime.now()) + ' -> ' + u'加载上传文件[完成]' + '<br/>'
    return file_list


def All():
    u"""获取目录列表"""
    file_list = []
    global msg
    msg = msg + str(datetime.now()) + ' -> ' + u'加载golsee文件...' + '<br/>'
    for root, dirs, files in os.walk(BASEDIR):
        if root not in [BACKUP_DIR, LOG_DIR, os.path.join(BASEDIR, '.git'), os.path.join(BASEDIR, '.idea')]:
            for name in files:
                if not name[-3:] == 'pyc':
                    file_list.append(os.path.join(root, name))
    msg = msg + str(datetime.now()) + ' -> ' + u'加载golsee文件[完成]' + '<br/>'
    return file_list


def Db():
    """备份数据库"""
    global msg
    msg = msg + str(datetime.now()) + ' -> ' + u'备份数据库...' + '<br/>'
    db_user = database.engine.url.username
    db_pwd = database.engine.url.password
    db_host = database.engine.url.host
    db_name = database.engine.url.database
    sql_file = os.path.join(BACKUP_DIR, format_name('db', 'sql'))
    backup_sql = 'mysqldump -u' + db_user + ' -p' + db_pwd + ' -h' + db_host + ' ' + db_name + ' > ' + sql_file
    subprocess.Popen(backup_sql, shell=True,
                     stdout=subprocess.PIPE,
                     stderr=subprocess.PIPE)
    t = 10
    while t >= 0:
        msg = msg + str(datetime.now()) + ' -> ' + u'等待数据库备份完成' + '<br/>'
        time.sleep(1)
        if os.path.exists(sql_file):
            t = -1
        else:
            t -= 1
    if os.path.exists(sql_file):
        msg = msg + str(datetime.now()) + ' -> ' + u'数据库备份完成。文件：' + sql_file + '<br/>'
    else:
        msg = msg + str(datetime.now()) + ' -> ' + u'数据库备份失败。找不到文件：' + sql_file + '<br/>'
    msg = msg + str(datetime.now()) + ' -> ' + u'备份文件：' + sql_file + '<br/>'
    msg = msg + str(datetime.now()) + ' -> ' + u'备份数据库[完成]' + '<br/>'
    return sql_file


@BackupManager.command
def full():
    """备份整个blog"""
    global msg
    msg = msg + str(datetime.now()) + ' -> ' + u'执行全备份' + '<br/>'
    zip_name = format_name('golsee', 'zip')
    zip_file = os.path.join(BACKUP_DIR, zip_name)
    file_list = All()
    file_list.append(Db())
    my_zip(file_list, zip_file)
    msg = msg + str(datetime.now()) + ' -> ' + u'执行全备份[完成]' + '<br/>'
    backup_mail(zip_file, msg)


@BackupManager.command
def auto():
    u"""默认备份（附件及数据库）"""
    global msg
    msg = msg + str(datetime.now()) + ' -> ' + u'执行默认备份' + '<br/>'
    file_list = Uploads()
    file_list.append(Db())
    zip_name = format_name('golsee', 'zip')
    zip_file = os.path.join(BACKUP_DIR, zip_name)
    my_zip(file_list, zip_file)
    msg = msg + str(datetime.now()) + ' -> ' + u'执行默认备份[完成]' + '<br/>'
    backup_mail(zip_file, msg)


@BackupManager.command
def uploads():
    u"""备份上传文件"""
    global msg
    msg = msg + str(datetime.now()) + ' -> ' + u'备份上传文件' + '<br/>'
    file_list = Uploads()
    zip_name = format_name('uploads', 'zip')
    zip_file = os.path.join(BACKUP_DIR, zip_name)
    my_zip(file_list, zip_file)
    msg = msg + str(datetime.now()) + ' -> ' + u'备份上传文件[完成]' + '<br/>'
    backup_mail(zip_file, msg)


def file_zip(file_dir, zip_file_dir, excepts=None):
    """压缩文件"""
    file_list = list()
    zf = zipfile.ZipFile(zip_file_dir,
                         "a", zipfile.zlib.DEFLATED)
    if os.path.isfile(file_dir):
        arcname = os.path.basename(file_dir)
        zf.write(file_dir, arcname)
    else:
        for root, dirs, files in os.walk(file_dir):
            if root not in excepts:
                for name in files:
                    file_list.append(os.path.join(root, name))
        if zip_file_dir in file_list:
            file_list.remove(zip_file_dir)
        if excepts is not None:
            for exc in excepts:
                if exc in file_list:
                    file_list.remove(exc)
        for target in file_list:
            arcname = target[len(file_dir):]
            zf.write(target, arcname)
    zf.close()


def my_zip(file_list, zip_file):
    u'''压缩文件'''
    global msg
    zf = zipfile.ZipFile(zip_file,
                         "a", zipfile.zlib.DEFLATED)
    for target in file_list:
        arcname = target[len(BASEDIR):]
        zf.write(target, arcname)
        msg = msg + str(datetime.now()) + ' -> ' + arcname + u' 已写入文件 ' + zip_file + '<br/>'
    zf.close()


def format_name(st, type):
    import time
    from datetime import datetime

    return 'backup_' + st + '_' + str(time.mktime(time.strptime(str(datetime.now())[:19],
                                                                "%Y-%m-%d %H:%M:%S")))[:10] + '.' + type
